<?php

namespace app\common\command;

use payment\{WorldFirstService, AirwallexService, SlashService};
use think\console\Command;
use think\console\Input;
use think\console\Output;
use app\common\model\card\Card;
use think\facade\Log;

class UpdateCardStatus extends Command
{
    protected function configure()
    {
        $this->setName('update_card_status')
            ->setDescription('更新卡状态');
    }

    protected function execute(Input $input, Output $output)
    {
        // 创建锁文件
        $lockFile = runtime_path() . 'lock/update_card_status.lock';
        $lockDir = dirname($lockFile);

        // 确保锁目录存在
        if (!is_dir($lockDir)) {
            mkdir($lockDir, 0755, true);
        }

        // 尝试获取文件锁
        $fp = fopen($lockFile, 'w+');
        if (!$fp) {
            // 使用 trace() 函数记录错误，这个更可靠
            trace('无法创建锁文件: ' . $lockFile, 'error');
            return false;
        }

        // 尝试获取独占锁
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            Log::channel('card_status')->info('任务正在执行中，跳过本次执行');
            fclose($fp);
            return false;
        }

        try {
            // 写入进程ID和时间戳
            $lockInfo = [
                'pid' => getmypid(),
                'start_time' => date('Y-m-d H:i:s'),
                'memory_usage' => memory_get_usage(true)
            ];
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            Log::channel('card_status')->info('开始执行卡片状态更新命令');

            // 更新万里付卡片状态
            $worldFirstCards = Card::where('card_bin', 10)->select()->toArray();
            Log::channel('card_status')->info('查询到万里付卡片数量: ' . count($worldFirstCards));

            $worldFirstSuccess = 0;
            $worldFirstFail = 0;
            $worldFirstUpdated = 0;

            $worldFirst = new WorldFirstService('worldfirst');
            foreach ($worldFirstCards as $card) {
                if ($this->updateWorldFirstCardStatus($card, $worldFirst)) {
                    $worldFirstSuccess++;
                } else {
                    $worldFirstFail++;
                }
            }
            Log::channel('card_status')->info("万里付卡片状态更新完成 - 成功: {$worldFirstSuccess}, 失败: {$worldFirstFail}, 状态变更: {$worldFirstUpdated}");

            // 更新香港万里付卡片状态
            $worldFirstCards = Card::where('card_bin', 13)->select()->toArray();
            Log::channel('card_status')->info('查询到香港万里付卡片数量: ' . count($worldFirstCards));

            $worldFirstSuccess = 0;
            $worldFirstFail = 0;
            $worldFirstUpdated = 0;

            $worldFirst = new WorldFirstService('worldfirst_hk');
            foreach ($worldFirstCards as $card) {
                if ($this->updateWorldFirstCardStatus($card, $worldFirst)) {
                    $worldFirstSuccess++;
                } else {
                    $worldFirstFail++;
                }
            }
            Log::channel('card_status')->info("香港万里付卡片状态更新完成 - 成功: {$worldFirstSuccess}, 失败: {$worldFirstFail}, 状态变更: {$worldFirstUpdated}");


            // 更新slash卡片状态
            $slashCards = Card::where('card_bin', 12)->select()->toArray();
            Log::channel('card_status')->info('查询到slash卡片数量: ' . count($slashCards));

            $slashSuccess = 0;
            $slashFail = 0;
            $slashUpdated = 0;

            $slashService = new SlashService(12);
            foreach ($slashCards as $card) {
                if ($this->updateSlashCardStatus($card, $slashService)) {
                    $slashSuccess++;
                } else {
                    $slashFail++;
                }
            }

            Log::channel('card_status')->info("slash卡片状态更新完成 - 成功: {$slashSuccess}, 失败: {$slashFail}, 状态变更: {$slashUpdated}");

            $slashCards = Card::where('card_bin', 15)->select()->toArray();
            Log::channel('card_status')->info('查询到slash卡片数量: ' . count($slashCards));

            $slashSuccess = 0;
            $slashFail = 0;
            $slashUpdated = 0;

            $slashService = new SlashService(15);
            foreach ($slashCards as $card) {
                if ($this->updateSlashCardStatus($card, $slashService)) {
                    $slashSuccess++;
                } else {
                    $slashFail++;
                }
            }

            Log::channel('card_status')->info("slash_12卡片状态更新完成 - 成功: {$slashSuccess}, 失败: {$slashFail}, 状态变更: {$slashUpdated}");

            $output->writeln("所有卡片状态更新完成");
            Log::channel('card_status')->info('卡片状态更新命令执行完成');

            // 更新锁文件信息，记录完成时间
            $lockInfo['end_time'] = date('Y-m-d H:i:s');
            $lockInfo['status'] = 'completed';
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            return true;

        } catch (\Exception $e) {
            Log::channel('card_status')->error('卡片状态更新命令执行失败: ' . $e->getMessage());

            // 更新锁文件信息，记录错误状态
            $lockInfo['end_time'] = date('Y-m-d H:i:s');
            $lockInfo['status'] = 'error';
            $lockInfo['error'] = $e->getMessage();
            ftruncate($fp, 0);
            fwrite($fp, json_encode($lockInfo));
            fflush($fp);

            return false;

        } finally {
            // 释放锁并关闭文件
            flock($fp, LOCK_UN);
            fclose($fp);
        }
    }

    /**
     * 更新万里付卡片状态
     * @param array $card
     * @param WorldFirstService $worldFirst
     * @return bool
     */
    private function updateWorldFirstCardStatus($card, $worldFirst)
    {
        try {
            Log::channel('worldfirst_status')->info('开始更新万里付卡片状态: ' . $card['card_nick_name']);

            $worldFirstResult = $worldFirst->getCardDetail($card['card_id']);
            Log::channel('worldfirst_status')->info('万里付获取卡片详情');
            Log::channel('worldfirst_status')->info(json_encode($worldFirstResult));

            if (!isset($worldFirstResult['cardStatus'])) {
                Log::channel('worldfirst_status')->error('万里付获取卡片状态失败: ' . ($worldFirstResult['message'] ?? '未知错误'));
                return false;
            }

            $newStatus = $worldFirstResult['cardStatus'] == 'ACTIVE' ? 1 : 0;
            $oldStatus = $card['status'];

            if ($oldStatus != $newStatus) {
                Log::channel('worldfirst_status')->info("万里付卡片状态变更 - 卡片: {$card['card_nick_name']}, 旧状态: {$oldStatus}, 新状态: {$newStatus}");
                
                Card::where('id', $card['id'])->update(['status' => $newStatus]);
                
                Log::channel('worldfirst_status')->info('万里付卡片状态更新成功');
                return true;
            } else {
                Log::channel('worldfirst_status')->info("万里付卡片状态无变化 - 卡片: {$card['card_nick_name']}, 状态: {$oldStatus}");
                return true;
            }

        } catch (\Exception $e) {
            Log::channel('worldfirst_status')->error('万里付卡片状态更新异常: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * 更新slash卡片状态
     * @param array $card
     * @param SlashService $slashService
     * @return bool
     */
    private function updateSlashCardStatus($card, $slashService)
    {
        try {
            Log::channel('slash_status')->info('开始更新slash卡片状态: ' . $card['card_nick_name']);

            $result = $slashService->getCardInfo($card['card_id']);
            Log::channel('slash_status')->info('slash获取卡片信息');
            Log::channel('slash_status')->info(json_encode($result));

            if (!isset($result['status'])) {
                Log::channel('slash_status')->error('slash获取卡片状态失败: ' . ($result['message'] ?? '未知错误'));
                return false;
            }

            $newStatus = 0; // 默认状态为0
            if ($result['status'] == 'active') {
                $newStatus = 1;
            } else if ($result['status'] == 'paused' || $result['status'] == 'closed') {
                $newStatus = 0;
            }

            $oldStatus = $card['status'];

            if ($oldStatus != $newStatus) {
                Log::channel('slash_status')->info("slash卡片状态变更 - 卡片: {$card['card_nick_name']}, 旧状态: {$oldStatus}, 新状态: {$newStatus}, API状态: {$result['status']}");
                
                Card::where('id', $card['id'])->update(['status' => $newStatus]);
                
                Log::channel('slash_status')->info('slash卡片状态更新成功');
                return true;
            } else {
                Log::channel('slash_status')->info("slash卡片状态无变化 - 卡片: {$card['card_nick_name']}, 状态: {$oldStatus}, API状态: {$result['status']}");
                return true;
            }

        } catch (\Exception $e) {
            Log::channel('slash_status')->error('slash卡片状态更新异常: ' . $e->getMessage());
            return false;
        }
    }
}